package game.module.payment.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import game.common.DaoCommonHandler;
import game.db.DataSourceManager;
import game.module.payment.bean.PaymentBean;

public class PaymentLogDao {

	private static Logger logger = LoggerFactory.getLogger(PaymentLogDao.class);

	private DataSource dataSource = DataSourceManager.getInstance().getDataSource();

	static class SingletonHolder {
		static PaymentLogDao instance = new PaymentLogDao();
	}

	public static PaymentLogDao getInstance() {
		return SingletonHolder.instance;
	}

	private ResultSetHandler<Set<Integer>> multiPlayerIdHandler = new ResultSetHandler<Set<Integer>>() {
		@Override
		public Set<Integer> handle(ResultSet rs) throws SQLException {
			Set<Integer> userBeanSet = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());
			while (rs.next()) {
				userBeanSet.add(rs.getInt(1));
			}
			return userBeanSet;
		}
	};

	private ResultSetHandler<PaymentBean> onePaymentHandler = new ResultSetHandler<PaymentBean>() {
		@Override
		public PaymentBean handle(ResultSet rs) throws SQLException {
			PaymentBean bean = null;
			if (rs.next()) {
				bean = new PaymentBean();
				bean.setAdd_point(rs.getInt("add_point"));
				bean.setAdd_time(rs.getTimestamp("add_time"));
				bean.setId(rs.getInt("Id"));
				bean.setItemId(rs.getInt("item_id"));
				bean.setOpen_id(rs.getString("open_id"));
				bean.setPay_money(rs.getInt("pay_money"));
				bean.setPay_status(rs.getInt("pay_status"));
				bean.setPay_way(rs.getString("pay_way"));
				bean.setPlayer_id(rs.getInt("player_id"));
				bean.setProduct_id(rs.getInt("product_id"));
				bean.setReward_diamond(rs.getInt("reward_diamond"));
				bean.setTransaction_code(rs.getString("transaction_code"));
			}
			return bean;
		}
	};

	public boolean saveTopupLog(int playerId, int productId, String transactionCode, int addPoint, String openId) {
		boolean addRet = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			int ret = runner.update("insert into log_topup(player_id,product_id,transaction_code,add_point,open_id,add_time) values(?,?,?,?,?,NOW())", playerId, productId,
					transactionCode, addPoint, openId);
			if (ret > 0) {
				addRet = true;
			}
		} catch (SQLException e) {
			logger.error("", e);
		}
		return addRet;
	}

	public boolean checkRechargeExist(int producetId, String openId, int serverId) {
		boolean ret = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			ret = runner.query("SELECT EXISTS(select 1 from log_topup where open_id = ? and product_id=?)", DaoCommonHandler.Booleanhandler, openId, producetId);
		} catch (SQLException e) {
			logger.error("", e);
			return ret;
		}
		return ret;
	}

	public boolean saveRewardDiamond(int playerId, int rewardDiamond, String openId, int serverId) {
		boolean addRet = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			int ret = runner.update("insert into log_topup(player_id,reward_diamond,open_id,server_id,add_time) values(?,?,?,?,NOW())", playerId, rewardDiamond, openId, serverId);
			if (ret > 0) {
				addRet = true;
			}
		} catch (SQLException e) {
			logger.error("", e);
		}
		return addRet;
	}

	public boolean checkOrderExist(String orderId) {
		boolean ret = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			ret = runner.query("SELECT EXISTS(select 1 from log_topup where transaction_code = ?)", DaoCommonHandler.Booleanhandler, orderId);
		} catch (SQLException e) {
			logger.error("", e);
			return ret;
		}
		return ret;
	}

	public Set<Integer> getPaymentPlayers() {
		Set<Integer> retSet = new HashSet<>();
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			retSet = runner.query("SELECT distinct(player_id) from log_topup", multiPlayerIdHandler);
		} catch (SQLException e) {
			logger.error("", e);
		}
		return retSet;
	}

	/**
	 * 
	 * 小7平台特殊处理
	 * 
	 * @param playerId
	 * @param transactionCode
	 * @param productId
	 * @param openId
	 * @return
	 */

	public boolean saveToPayTopupLog(int playerId, String transactionCode, int productId, String openId, int serverId) {
		boolean addRet = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			int ret = runner.update("insert into log_topup(player_id,transaction_code,product_id,open_id,add_time,status) values(?,?,?,?,NOW(),0)", playerId, transactionCode,
					productId, openId);
			if (ret > 0) {
				addRet = true;
			}
		} catch (SQLException e) {
			logger.error("", e);
		}
		return addRet;
	}

	public void updatePayLog(int add_point, String transaction_code) {
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			runner.update("update log_topup set add_point = ?,status = 1 where transaction_code = ?", add_point, transaction_code);
		} catch (SQLException e) {
			logger.error("", e);
		}
	}

	public int getToPayProductId(String orderId) {
		int ret = -1;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			ret = runner.query("select product_id from log_topup where transaction_code = ? and status = 0", DaoCommonHandler.Integerhandler, orderId);
		} catch (SQLException e) {
			logger.error("", e);
			return ret;
		}
		return ret;
	}

	public boolean saveTopupLogBean(PaymentBean bean) {
		boolean addRet = false;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			int ret = runner.update(
					"insert into log_topup(transaction_code,add_point,reward_diamond,player_id,product_id,open_id,pay_status,pay_way,pay_money,add_time,item_id) values(?,?,?,?,?,?,?,?,?,NOW(),?)",
					bean.getTransaction_code(), bean.getAdd_point(), bean.getReward_diamond(), bean.getPlayer_id(), bean.getProduct_id(), bean.getOpen_id(), bean.getPay_status(),
					bean.getPay_way(), bean.getPay_money(), bean.getItemId());
			if (ret > 0) {
				addRet = true;
			}
		} catch (SQLException e) {
			logger.error("", e);
		}
		return addRet;
	}

	public PaymentBean getPaymentByOrderId(String orderId) {
		PaymentBean ret = null;
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			ret = runner.query("SELECT * from log_topup where transaction_code = ?  ", onePaymentHandler, orderId);
		} catch (SQLException e) {
			logger.error("", e);
			return ret;
		}
		return ret;
	}

	public void finishPaymentStatus(String transaction_code, int pay_status) {
		if (pay_status == 0) {
			logger.error("error not finish status orderId={}", transaction_code);
			return;
		}
		QueryRunner runner = new QueryRunner(dataSource);
		try {
			runner.update("update log_topup set pay_status = ?,finish_time=NOW() where transaction_code = ?", pay_status, transaction_code);
		} catch (SQLException e) {
			logger.error("", e);
		}
	}

}
